package org.fjsei.yewu.pojo;

import io.camunda.tasklist.dto.Task;         //注意包名不一样啊;
import io.camunda.tasklist.dto.TaskState;
import io.camunda.tasklist.dto.Variable;
import io.camunda.tasklist.dto.VariableType;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.fjsei.yewu.graphql.AfterValues;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.List;

/** 从camunda-tasklist-client-java/io/camunda/tasklist/dto/Task.java映射过来的；
 * 倒腾了一手。挺像是API路由转发机制的功能。
 * 实际两次graphQL模型做法不同。第一次后端服务器请求tasklist服务返回给出的graphQl通用但Task前端不友好，第二次是我服务端给前端的graphQl应答UserTask。
     type Task {
        variables: [Variable]
     }
     type Variable {
         name: String!
         value: String!  【问题】虽然服务端可以提供该字段的，可我用camunda-tasklist-client-java读取的，@我这无法获取这个字段。
         previewValue: String!   但是previewValue存在太多被断截可能。 可惜我这用implementation 'io.camunda:camunda-tasklist-client-java:1.0.2'来访问，被它限制了。
     }
* */

@Getter
@Setter
@NoArgsConstructor
public class UserTask implements AfterValues {
    /**这里 UserTask id也即是camunda-tasklist服务页面上给出的ID，和camunda-operate服务网页看见的流程实例底下当前用户节点的id其实不相等的!；
     * 所以只能使用自定义流程变量来识别到底是哪一个申请单或报告流转的流程实例关联实体：ent参数代表(流程)关联DB数据库实体ID，数据库状态机进一步挂接zeebe流程实例id；
     * */
    private String id;

    /**当前节点的  汉语名字
     * */
    private String name;
    /**当前流程定义的  汉语名字
     * */
    private String processName;
    /**当前分配給 特定的某一个用户。
     * 若是用户组就要 Claimed;
     * */
    private String assignee;
    /**支持 用户组组名字 来识别的。
     * */
    private List<String> candidateGroups;
    /**用户任务的生成时间
     * */
    private LocalDateTime  creationTime;
    /**流程某个用户任务的当前状态
     * */
    private TaskState  taskState;

    private List<String>  sortValues;

    private Boolean  isFirst;

    //方便在前端的使用便利： K/V ?拆解掉的 ,原来tasklist服务器发过来的是List<Variable> variables直接给前端是[Variable]还需要for循环搜索提取某个特定标签名的变量取值啊。不爽！
    //我这中间倒一手顺便做个转换：把variables分解出来适配graphQL给前端： 常用的名字固定下来了： 如下Variable变量。自定义改造约束缺点：就是规范名字，变量名字字段扩充需求改代码。

    /**通知给用户应该点击转入的审批的URL连接地址, 进入该uri后进行审批操作(流程)
     * */
    private String  uri;
    /**挂接的申请单或报告的GlobalID; 代表(流程)关联DB数据库实体ID，数据库状态机进一步挂接zeebe流程实例id；
     * */
    private String  ent;
    /**审核 备注，回退的要说明理由
     * */
    private String  memo;
    /**本环节预期的设定的：zeebe用户任务的到期时间；
     * */
    private LocalDateTime  expirationDate;
    /**本流程实例实际针对挂接的 申请单或报告的 主题标识：#给人阅读的！汉语描述；
     * */
    private String  topic;
    /**流程实例id；      通过 http://localhost:8271/processes/prId 操作
     * 数据库已经丢失了数据情形：状态机进一步挂接zeebe流程实例id；
     * */
    private String  prId;

    /**将从Tasklist{ graphQL }服务端获取的Task数据,转换映射为前端看的graphQL UserTask*/
    public UserTask(Task task) {
        this.id = task.getId();
        this.name =  task.getName();
        this.processName =  task.getProcessName();
        this.assignee = task.getAssignee();
        this.candidateGroups = task.getCandidateGroups();
        String creDate=task.getCreationTime().substring(0,26);
        this.creationTime= LocalDateTime.parse(creDate, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
        this.sortValues= task.getSortValues();

        //流程变量的K/V分解 把可变的标签变量，直接变身固定属性字段，可方便在前端的使用便利：更多个变量 ?
        //【流程都会设置的通用变量提取】zeebe流程变量：expirationDate，ent ,uri;
        if(null!=task.getVariables()) {
            for (Variable variable : task.getVariables()) {
                if(null==prId) {
                    String[] splits = variable.getId().split("-");
                    prId = splits[0];
                }
                if (variable.getName().equals("uri") && VariableType.STRING==variable.getType()) {
                    this.uri = (String) variable.getValue();
                }
                else if (variable.getName().equals("ent") && VariableType.STRING==variable.getType()) {
                    this.ent = (String) variable.getValue();
                }
                else if (variable.getName().equals("expirationDate") && VariableType.STRING==variable.getType()) {
                    Instant expiration= Instant.parse((String) variable.getValue());
                    this.expirationDate =LocalDateTime.ofInstant(expiration, ZoneId.of("Asia/Shanghai"));
                }
                else if (variable.getName().equals("topic") && VariableType.STRING==variable.getType()) {
                    this.topic = (String) variable.getValue();
                }
            }
        }
    }

    @Override
    public List<String> getAfterValues() {
        return sortValues;
    }
}

